Utilisateur:Arkanosis/xdone.js

Une page de Wikipédia, l'encyclopédie libre.
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/*
 * xdone — Mark tasks as done
 * (C) 2013-2021 Arkanosis <jroquet@arkanosis.net>
 * (C) 2017 Zebulon84 <wiki@zebulon84.com>
 * (C) 2017-2018 Od1n
 * Released under the MIT/X11 license
 */

// <nowiki>

/* autorise la "bracket notation" pour accéder aux propriétés */
/* jshint sub: true */

/* globals mw, $, importStylesheet */

( function () {
	'use strict';

	var relevantPages = [
		'Wikipédia:Demande_de_déblocage', // DDD
		'Wikipédia:Demande_de_protection_de_page', // DPP
		'Wikipédia:Demande_de_purge_d\'historique', // DPH
		'Wikipédia:Demande_de_renommage', // DR
		'Wikipédia:Demande_de_restauration_de_page', // DRP
		'Wikipédia:Demande_d\'intervention_sur_un_message_système', // DIMS
		'Wikipédia:Demande_d\'intervention_sur_une_page_protégée', // DIPP
		'Wikipédia:Requête_aux_administrateurs', // RA
		'Wikipédia:Vérificateur_d\'adresses_IP/Requêtes', // RCU
		'Discussion_MediaWiki:Spam-blacklist', // MWS
	];

	var configPage = 'MediaWiki:Préférences_des_Gadgets';

	var currentPage = mw.config.get( 'wgPageName' );

	if ( relevantPages.includes( currentPage ) ) {
		importStylesheet( 'User:Arkanosis/xdone.css' );
		bootstrap().then( function ( _option ) {
			Object.assign( _option, window.xdone_options );
			handleSections( _option );
		} );
	} else if ( currentPage === configPage ) {
		bootstrap();
	} else {
		return;
	}

	// Function defined during bootstrap
	var _i18n;

	function bootstrap() {
		var deferred = $.Deferred();
		mw.loader.using( [ 'mediawiki.util', 'user', 'user.options', 'ext.gadget.GadgetsPreferences' ], function () {
			mw.hook( 'gadgets-preferences.ready' ).add( function () {
				$( function ( $ ) {
					init_i18n();
					var _option = mw.gadgetsPreferences.register( 'xdone', 'xdone', {
						done_message: {
							'label': _i18n( 'done_message_label' ),
							'type': 'string',
							'default': _i18n( 'done_message' ),
							'help': _i18n( 'done_message_help' )
						}
					} );
					deferred.resolve( _option );
				} );
			} );
		} );
		return deferred.promise();
	}

	function init_i18n() {
		_i18n = ( function () {
			var nbsp = '\xA0'; // non-breaking space

			var l10n = {
				fr: {
					summary: '[[Discussion_utilisateur:Arkanosis/xdone.js|xdone]]' + nbsp + ': fait',
					done_message: '{{Fait}} ~~~~',
					done_message_label: 'Message à apposer',
					done_message_help: 'Pensez à inclure "~~~~" à la fin pour que le message soit signé.'
				}
			};
			l10n[ 'nb' ] = l10n.no;
			l10n[ 'pt-br' ] = l10n.pt;

			var lang = mw.user.options.get( 'language' );
			if ( !l10n[ lang ] ) {
				lang = 'fr';
			}

			return function ( key ) {
				if ( l10n[ lang ][ key ] ) {
					return l10n[ lang ][ key ];
				}
				return l10n[ 'fr' ][ key ];
			};
		}() );
	}

	function handleSections( _option ) {
		var _templates = '(DIMS|DIPP|DPH|DPP|DR|DRP|MWS|RA|RCU)';

		var _apiDone = function ( data ) {
			if ( data && data.edit && data.edit.result === 'Success' ) {
				window.location.reload();
			} else if ( data && data.error ) {
				alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
			} else {
				alert( 'Error: Unknown result from API.' );
			}
		};

		var _apiFail = function ( _ ) {
			alert( 'Error: Request failed.' );
		};

		var _getSectionValue = function ( $section ) {
			var $title = $section.prev( 'h2' );
			// fallback pour {{DR début}}
			if ( !$title.length ) {
				$title = $section.prev().prev( 'h2' );
			}
			// fallback pour avec Outils de discussion
			if ( !$title.length ) {
				$title = $section.prev( '.mw-heading' ).find( 'h2' );
			}
			// fallback pour {{DR début}} avec Outils de discussion
			if ( !$title.length ) {
				$title = $section.prev().prev( '.mw-heading' ).find( 'h2' );
			}
			if ( !$title.length ) {
				return;
			}

			var link = $title.find( '.mw-editsection' ).find( 'a' )[ 0 ];
			if ( !link ) {
				return;
			}

			var sectionMatch = /[?&]section=([^&]+)/.exec( link.search );
			if ( !sectionMatch ) {
				return;
			}

			return decodeURIComponent( sectionMatch[1].replaceAll( '+', ' ' ) );
		};

		$( '#mw-content-text' ).find( '.request-pending' ).each( function ( _, section ) {
			var $section = $( section );

			var sectionValue = _getSectionValue( $section );
			if ( !sectionValue ) {
				return;
			}

			var $status = $section.find( '.request-status' );
			if ( !$status.length ) {
				return;
			}

			var $button = $( '<a class="xdone-button">marquer comme traité</a>' ).click( function () {
				$.get(
					mw.util.wikiScript( 'api' ),
					{
						format: 'json',
						action: 'query',
						titles: mw.config.get( 'wgPageName' ),
						prop: 'revisions',
						rvprop: 'content',
						rvsection: sectionValue,
						rvslots: 'main',
						formatversion: 2
					}
				).done( function ( data ) {
					var revision = data.query.pages[ 0 ].revisions[ 0 ].slots.main;
					if ( revision.nosuchsection ) {
						return;
					}
					var text = revision.content;
					[
						[ '<!-- S\'il vous plaît, n\'utilisez pas de modèles ou de liens internes dans le titre de votre requête -->', '' ],
						[ '<!-- Indiquez votre requête ici -->', '' ],
						[ '<!-- Indiquez le titre exact de l\'article dans le modèle {{a-court}} ci-dessus-->', '' ],
						[ '<!-- Écrivez dans la boîte \'\'Sujet/titre\'\' ci-dessus : [[MediaWiki:nom de la page]], puis remplissez les rubriques ci-dessous -->', '' ],
						[ '<!-- Ne pas modifier la ligne ci-avant -->', '' ],
						[ '<!-- Ne pas modifier la ligne ci-après -->', '' ],
						[ '<!-- Ne pas modifier la ligne qui précède -->', '' ],
						[ '<!-- Ne pas modifier la ligne qui suit -->', '' ],
						[ '<!-- NE PAS MODIFIER NI ÉCRIRE SOUS LA LIGNE CI-APRÈS -->', '' ],
						[ '<!-- toujours écrire au-dessus de cette ligne -->', '' ],
						[ / *<!-- ne pas modifier cette ligne -->/ig, '' ],
						[ ' <!-- Indiquez votre justification ici -->', '' ],
						[ '<!-- Indiquez votre requête après cette ligne -->', '' ],
						[ '<!--  L\'intervention d\'un administrateur n\'est pas nécessaire si l\'historique de l\'article qui porte le nom cible ne contient qu\'une ligne et que son contenu est une redirection vers le titre actuel.  -->', '' ],
						[ /\n\n\n*/g, '\n\n' ],
						[ new RegExp('\\{\\{' + _templates + ' début\\|(traitée|statut)=\\|date=(<!--~~~~~-->)?\\}\\}( *<!-- ne pas modifier cette ligne -->)?\n+', 'g'), '{{$1 début|$2=oui|date=~~~~~}}\n' ],
						[ new RegExp('\n*\\{\\{' + _templates + ' fin\\}\\}', 'g'), '\n:' + _option[ 'done_message' ] + '\n{{$1 fin}}' ],
						[ new RegExp('(\n:[^:\n][^\n]*\n)(:[^\n]*\n\\{\\{' + _templates + ' fin\\}\\})', 'g'), '$1\n$2' ],
						[ new RegExp('\\{\\{Dd\\|statut=\\|date=<!--~~~~~-->\\}\\}([\\S\\s]*)'), function ( match, p1 ) {
							// p1 contains absolutely everything that follows the template
							var match = p1.match( /\n(:*).+\n*$/ ); // try to guess indent level of last line
							var replyIndentLevel = match ? ( match[ 1 ].length + 1 ) : 1;
							var reply = ':'.repeat( replyIndentLevel ) + _option[ 'done_message' ];
							return '{{Dd|statut=oui|date=~~~~~}}' + p1.replace(/\n+$/, '') + '\n' + reply + '\n';
						} ],
					].forEach( function ( pattern ) {
						text = text.replace( pattern[ 0 ], pattern[ 1 ] );
					} );
					var summary = text.split( '\n' )[ 0 ];
					[
						[ /^== */, '' ],
						[ / *==.*/, '' ]
					].forEach( function ( pattern ) {
						summary = summary.replace( pattern[ 0 ], pattern[ 1 ] );
					} );
					$.post(
						mw.util.wikiScript( 'api' ),
						{
							format: 'json',
							action: 'edit',
							title: mw.config.get( 'wgPageName' ),
							section: sectionValue,
							summary: '/* ' + summary + ' */ ' + _i18n( 'summary' ),
							minor: 'true',
							text: text,
							token: mw.user.tokens.get( 'csrfToken' )
						}
					).done( _apiDone ).fail( _apiFail );
				} ).fail( _apiFail );
			} );

			$status.append( ' ', $button );
		} );
	}

}() );

// </nowiki>